<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<title>AXL Tutorial: TranzAm</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- menu -->
	<div id="navmain">
	<ul>
		<li><a href="index.html">Overview</a></li>
		<li><a href="install.html">Installation</a></li>
		<li><a href="config.html">Configurator</a></li>
		<li><a href="animation.html">Animation</a></li>
		<li><a href="framework.html">Framework</a></li>
		<li><a href="tranzam.html">Tutorial</a></li>
	</ul>
	</div>
	<div id="navsub">
	<ul>
		<li><a href="tranzam.html">Start</a></li>
		<li><a href="tranzam_a1.html">Article 1</a></li>
		<li><a href="tranzam_a2.html">Article 2</a></li>
		<li><a href="tranzam_a3.html">Article 3</a></li>
		<li><a href="tranzam_a4.html">Article 4</a></li>
		<li><a href="tranzam_a5.html">Article 5</a></li>
		<li><a href="tranzam_a6.html">Article 6</a></li>
		<li><a href="tranzam_a7.html">Article 7</a></li>
		<li><a href="tranzam_a8.html">Article 8</a></li>
		<li><a href="tranzam_a9.html">Article 9</a></li>
		<li><a href="tranzam_a10.html">Article 10</a></li>
	</ul><span class="smallprint">This menu will stay fixed with a proper browser.</span>
	<p>
	 <a href="http://jigsaw.w3.org/css-validator/">
	  <img style="border:0;width:88px;height:31px"
		   src="http://jigsaw.w3.org/css-validator/images/vcss" 
		   alt="Valid CSS!" />
	 </a>
	</p>
	<p>
      <a href="http://validator.w3.org/check?uri=referer"><img
          src="http://www.w3.org/Icons/valid-xhtml10"
          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
    </p>
<p><a href="http://www.bloggerheads.com/bbc/"><img src="http://www.bloggerheads.com/bbc/bbc.gif" width="90" height="45"  
alt="Click here to find out why." /></a></p>
<p><a href="http://retrospec.sgn.net" ><img src="retrospec.gif" width="150" alt="Fine games" /></a></p>
	</div>
<!-- menu -->

	<div id="main">
	<a name="files"></a>
<h1>Introduction</h1>
In the previous lesson we learnt about the A-Star algorithm and produced a test program. In this lesson we will apply it to the game to allow
every enemy to track the player when in range. There will be no movement in this lesson, just the application of the A-Star algorithm.
<h1>Structure</h1>
If you are manually creating the project 
    make file then use the one from lesson 8 and add the file game_astar.cpp.
    <br />The following files will be changed in this lesson:
    <ul>
    <li>game_astar.cpp : The A-Star algorithm added</li>
    <li>game_car.cpp : Enemy cars apply A-Star path finding algorithm</li>
    <li>game_game.cpp: Drawing of the enemy path to the player drawn, A-Star map updates</li>
    <li>game_vars.cpp: extra variables to control the enemies</li>
    </ul>
	<a name="source1"></a>
<h1>Tranzam</h1>
The idea for the enemy car movement is that they will remain where they are until 
the player comes in range (about 40 tiles - 3 screens worth). When in range an enemy will 
start using the path finding algorithm to track and follow the user. 
<br />Because the player is moving most of the time, we need to update each enemy's path, otherwise
it will never find the player. Obviously doing so every frame is overkill and will slow down the game
too much, so the Animation's custom countdown timer will be used to redo the path every few seconds. 
Having this at a random amount may give it a human touch as it will appear that the computer is 
not that good if the delay is large, and if there are multiple enemies on screen at once, they will drive differently.
<br />
The code to be written will be similar to that which we used in the previous lesson for the path finding,
so hopefully will make perfect sense :)
<br />To see what it is that this code will do, compile and run the program. Remember that on the 
national map the enemies are in blue. Finding two or more close together will show how they can all 
generate their own paths. Below is a screenshot of the path-finding in action.
<img src="images/tranzam_found.jpg" alt="found" />

<h1>Code Walkthrough of game_Vars.cpp/game_transam.h</h1>
In the previous lesson we discussed that we need a simple integer based (1-dimensional) array 
to represent open and blocked tiles (we aren't using weighted tiles, e.g. we could add extra 
weight to the water, grass, mud, etc). In game_Vars.cpp we create our global reference
to this as <span class="code">int* AstarMap</span>
<br />In the game_transam.h file we add the game_astar.h header file and a function, RegenerateAstarMap. This
function populates our A-Star array, AstarMap, from our TranzAm Mappy map. We will be calling this 
function (i.e. regenerating the 1-dimensional array) whenever the map is loaded and whenever it changes. 
It only changes when the player dies (when the player dies a gravestone is added to the game that acts
as a collision item - which was done a few lessons previously).

<h1>game_car.cpp/h Code Walkthrough)</h1>
The A-Star algorithm is wrapped up in the class AStarClass. We will be giving each enemy their own
AStarClass to track the player. It will be initialised within the constructor and destroyed in the 
destructor. We will also be storing a flag to show that we have a path for the enemy car.
<br />
The updates to the enemy class (within the game_car.h header file) are as follows:
<div class="code">
bool NextMove(Car* player);
EnemyCar() { Route=NULL; }
~EnemyCar() { if(Route) delete Route; }
bool RouteGenerated;
AstarClass* Route;
</div>
<br />
As you can see, Route is the name we will give the enemy's AStarClass. The method NextMove has been 
updated from the previous lesson, by passing in the Player's details. This is so the enemies can 
find out where the player is.

<h1>Code Walkthrough of game_car.cpp</h1>
Firstly minor update. The Mappy block variable 'user6' is used to determine if a tile makes the player bounce back. 
The original idea was to set the damage amount in the data, hence using the integer user6. However, 
all damage is to be the same, regardless of the tile type, so this is changed to use the bit field 'tl' (top-left tick box) instead.
<br />
In the SetupCar method for the Enemy, we create our AStarClass object: 
<div class="code">	
if(Route) delete Route;
Route=new AstarClass(AstarMap,mapwidth,mapheight,mapblockwidth);
</div>
This initialises the AStarClass using the global map array we mentioned earlier. 
<br />
In the EnemyCar method 'NextMove' (what is called every frame and updates the cars, collision detection, etc), 
it's position is checked against the Player. If it is within about 45 squares (no need to be exact, so no need 
for time consuming trig) then the A-Star system is invoked. 
<br />If the A-Star route has not been generated for the car a new path is created immediately 
and a timer is set for one second (this uses the animation object customer countdown timer). 
<br />If the A-Star route has been generated and the countdown timer has elapsed (i.e. one second has 
passed) then the path is regenerated and the timer reset back to one second.
<br />This can be seen within the EnemyCar::NextMove method by the statements
<div class="code">
this-&gt;car-&gt;SetCustomCountDown(1,1000);
Route-&gt;NewPath(mapx-(int)mapx%mapblockwidth,mapy-(int)mapy%mapblockwidth,player-&gt;mapx-(int)player-&gt;mapx%mapblockwidth,player-&gt;mapy-(int)player-&gt;mapy%mapblockwidth);
</div>
Which should, hopefully, be familiar. NewPath is the A-Star method for generating a path from A to B (in our case
from the enemy to the player), and SetCustomCountDown creates a countdown timer for the animation object.
<br />If the A-Star route has been generated and the timer has not finished we call a method that we 
haven't seen yet: ManualTimerUpdate()
<br />Basically, in our Player's car class we call NextMove() on the Car object which updates all the collisions and animations, etc. 
But for our enemy cars we don't really need this overhead. So because we aren't calling the animation NextMove method
we need a method of updating the timers. Which is what ManualTimerUpdate does.

<h1>game_game.cpp Code Walkthrough</h1>
Whenever a new level is initialised (new game, lost life) we regenerate our AStar version of the Mappy
map by calling <span class="code">RegenerateAstarMap()</span>. As with our previous lesson, this function 
loops through our game's array and creates a one-dimensional array of either 1's or 0's. An array element is set 
to 1 when a collidable tile is found and to 0 when it isn't.
<br />
Ultimately the Enemies will give chase when the player is in range. For this lesson we will simply 
draw the found path to the player using a series of rectangles for each of the nodes in the path.
 This is found as follows:
<div class="code">
if(Enemies[i]-&amp;gt;RouteGenerated &amp;&amp; abs(Enemies[i]-&amp;gt;mapx-Player-&amp;gt;mapx)&amp;lt;mapblockwidth*30 &amp;&amp; abs(Enemies[i]-&amp;gt;mapy-Player-&amp;gt;mapy)&amp;lt;mapblockwidth*30)
</div>
This means the following code will be called if a route has been generated and the player is within about 30 square tiles 
(again, avoiding using pythag. as it isn't needed, just an approximation).
<br />
As with our A-Star example, we loop through all the nodes (using NextNode) until the end has been 
reached (ReachedGoal). For each node we get the x and y and translate it to the screen, taking into 
account the offsets. We also draw a rectangle where the node is.

<h1>Allegro</h1>
Again, not much Allegro apart from drawing a rectangle. Most of the work was done by the A-Star and Animation 
classes. All that was done was we added an AStarClass object to each enemy, and whenever the player 
is within range, we updated the path and generated a one second (approximate) delay.
<h1>Next</h1>
The next lesson we will remove the temporary drawing code for the AStar and move the enemy car. Which 
should, hopefully, be the last lesson (bar closing comments).
</div>
</body>
</html>
